import Dayjs from 'dayjs';
import {isApp} from '@/lib/judge-env.js';

/**
 * 获取url上的query参数
 * @param {*} url
 * @returns
 */
function queryToJson(url) {
    if (!url) {
        url = window.location.href;
    }
    var query = url.substr(url.lastIndexOf('?') + 1),
        result = {},
        kv,
        key,
        value,
        item;
    if (query != url && query.indexOf('&') == -1) {
        query += '&';
    }
    query.split('&').forEach((param) => {
        if (param) {
            kv = param.split('=');
            key = kv[0];
            value = kv[1];
            item = result[key];
            if (typeof item === 'undefined') {
                result[key] = value;
            } else if (
                Object.prototype.toString.call(item) === '[object Array]'
            ) {
                item.push(value);
            } else {
                result[key] = [item, value];
            }
        }
    });
    return result;
}

/**
 * 深拷贝，如果只有一个参数，则默认第一个为数据源
 * @param {Object} target
 * @param {Object} source
 * @returns
 */
function deepCopy(target, source) {
    if (arguments.length === 1) {
        source = arguments[0];
        target = Array.isArray(source) ? [] : {};
    }
    if (!target) {
        throw Error('Cannot convert undefined or null to object');
    }
    Object.keys(source).forEach(keys => {
        if (source[keys] && typeof source[keys] === 'object') {
            target[keys] = deepCopy(source[keys])
        } else {
            target[keys] = source[keys]
        }
    })
    return target;
}

/**
 * 获取指定字符串的主域名，不传则为当前域名
 * @param {String} str 获取指定字符串的主域名，不传则为当前域名
 * @returns {String} 解析失败则返回空
 */
function getDomainV2(str) {
    str = str || window.location.hostname;
    let arr = str.match(/([a-zA-Z\d][a-zA-Z\d\-]*?\.(?:[a-zA-Z\d]+)(?:\.(?:[a-zA-Z\d]))*)([\/|\?].*)?$/i) || [];
    return arr.length > 1 ? arr[1] : '';
}

function dealDynamicTime(params) {
    const dayDiff = Dayjs(Dayjs(params).format('YYYY/MM/D')).diff(Dayjs(Dayjs().format('YYYY/MM/D')), 'day');
    const curWeekTime = [
        new Date(Dayjs().startOf('week').add(1, 'day')).getTime(),
        new Date(Dayjs().endOf('week').add(1, 'day')).getTime()
    ];
    let str = '';
    switch (dayDiff) {
        case -1:
            str = `昨天 ${Dayjs(params).format('HH:mm')}`;
            break;
        case 0:
            str = `${Dayjs(params).format('HH:mm')}`;
            break;
        default: {
            if (curWeekTime[1] >= params && params >= curWeekTime[0]) {
                let weekArr = [
                    '星期日',
                    '星期一',
                    '星期二',
                    '星期三',
                    '星期四',
                    '星期五',
                    '星期六'
                ];
                str = `${weekArr[new Date(params).getDay()]} ${Dayjs(
                    params
                ).format('HH:mm')}`;
                break;
            } else if (Dayjs(params).format('YYYY') == new Date().getFullYear()) {
                str = `${Dayjs(params).format('MM月DD日 HH:mm')}`;
                break;
            } else {
                str = `${Dayjs(params).format('YYYY年MM月DD日 HH:mm')}`;
                break;
            }
        }
    }
    return str;
}

class PollTask {

    constructor() {
        this.timer = null;
        this.abortState = false;
    }

    async startPoll(fn, validate, interval = 1000) {
        const resolver = async (resolve, reject) => {
          if(this.timer) {
              clearTimeout(this.timer)
          }
          try { // catch any error thrown by the "fn" function
            const result = await fn(); // fn does not need to be asynchronous or return promise
            // call validator to see if the data is at the state to stop the polling
            const valid = validate(result);
            console.log(valid);
            if (valid === true || this.abortState) {
               resolve(result);
            } else if (valid === false) {
               this.timer = setTimeout(resolver, interval, resolve, reject);
            } // if validator returns anything other than "true" or "false" it stops polling
          } catch (e) {
              clearTimeout(this.timer)
              reject(e);
          }
        };
        return new Promise(resolver);
    }

    abortPoll() {
        clearTimeout(this.timer);
        this.timer = null;
        this.abortState = true; 
    }
}
/**
 * 格式化时间
 * @param {*} val  单位s
 * @returns 
 */
 function fmtTime(val = 0) {
    let hour = Math.floor(val / 3600);
    let minute = Math.floor(val / 60 % 60);
    let second = Math.floor(val % 60);
    let fmtHour = hour > 9 ? hour : `0${hour}`;
    let fmtMinute = minute > 9 ? minute : `0${minute}`;
    let fmtSecond = second > 9 ? second : `0${second}`;

    if(hour > 0) {
        return `${fmtHour}:${fmtMinute}:${fmtSecond}`;
    }else {
        return `${fmtMinute}:${fmtSecond}`; 
    }
}

function getAcceptTypes(typeArr) {
    const defaultAcceptTypes = {
        document: ['doc', 'docx', 'ppt', 'pptx', 'txt', 'xls', 'xlsx', 'pdf', 'rtf', 'odt'],
        audio: ['mp3', 'wma', 'flac', 'm4a', 'ogg', 'ape', 'amr', 'wav', 'aac', 'aiff', 'caf'],
        video: ['mkv', 'rmvb', 'rm', 'wmv', 'avi', 'mp4', 'mov', 'mpg', 'asf', 'mpeg', 'vob', '3gp', 'flv', 'ts', 'mts', 'f4v', 'dv', 'm4v', 'mjpeg', 'swf', 'webm'],
        // video: ['mp4'],
        // img: ['bmp', 'jpg', 'jpeg', 'tiff', 'gif', 'pcx', 'tga', 'exif', 'fpx', 'svg', 'psd', 'cdr', 'pcd', 'dxf', 'ufo', 'eps', 'ai', 'raw', 'png'],
        img: ['png', 'jpeg', 'gif', 'jpg'],
        other: ['rar', 'zip'],
    };
    let types = []
    typeArr.forEach(t => {
        types.push(...defaultAcceptTypes[t]) 
    })
    return types || []
}

// 慕课错误信息
const errorMsgMap = {
    'delete': '很抱歉，该慕课已下线', // 删除
    'disabled': '很抱歉，该慕课已下线', // 禁用
    'unpublished': '很抱歉，当前慕课还未发布，敬请期待', // 未发布
    'notsignup': '还未报名慕课哦，请先报名', // 没报名
    'noauthority': '很抱歉，您暂无查看权限', // 没权限
    'deleteCatelogue': '该课件可能已经被删除' // 课件被删除
}

// 慕课错误页跳转
function handleErrorPage (type, moocId) {
    let myMoocHref =  { // 慕课详情页地址
        name: 'myMooc'
    };

    let pageMessage = {
        titleShow: true,
        title: errorMsgMap[type],
        btnShow: true,
        target: myMoocHref,
        buttonLabel: '返回'
    }

    switch(type) {
        case 'unpublished': // 课程没发布
            pageMessage.code = 1001;
            break
        case 'notsignup': // 没报名
            pageMessage.code = 1002;
            break
        case 'delete': // 课程删除或者禁用 禁用课程 30800500 删除课程 30800404
            pageMessage.code = 30800404;
            break
        case 'deleteCatelogue': // 当前课程目录被删除或者不存在
            pageMessage.code = 10000002;
            break

    }
    console.log(pageMessage, '=========pageMessage==========')
    G_dispatchEvent('toErrorPage', pageMessage);
}
/**
 * 函数节流
 * @param fn
 * @param interval
 * @returns {Function}
 * @constructor
 */
 function Throttle(fn, t) {
    let last
    let timer
    const interval = t || 500
    return function() {
        const args = arguments
        const now = +new Date()
        if (last && now - last < interval) {
        clearTimeout(timer)
        timer = setTimeout(() => {
            last = now
            // console.log("实际执行函数（" + interval + "）：" + typeof fn)
            fn.apply(this, args)
        }, interval)
        } else {
        last = now
        // console.log("实际执行函数（" + interval + "）：" + typeof fn)
        fn.apply(this, args)
        }
    }
}


export {
    Throttle,
    fmtTime,
    queryToJson,
    deepCopy,
    getDomainV2,
    dealDynamicTime,
    PollTask,
    getAcceptTypes,
    handleErrorPage
}
